home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / EDIT_UTL / TRIVED09 / SERIO.PAS < prev    next >
Pascal/Delphi Source File  |  1995-04-16  |  16KB  |  863 lines

  1. {serio.pas begins}
  2.  
  3. {serio:  header begins}
  4.  
  5. {
  6.  
  7. serio.pas - nonconsole input/output routines - modified slightly from rusnews
  8.  
  9. Russell Schulz - russell@alpha3.ersys.edmonton.ab.ca (940327)
  10.  
  11. Copyright 1995 Russell Schulz
  12.  
  13. this code is not in the Public Domain
  14.  
  15. version 3
  16.  
  17. permission is granted to use these routines in any application regardless
  18. of commercial status as long as the author of these routines assumes no
  19. liability for any damages whatsoever for any reason.  have fun.
  20.  
  21. assumes a fossil/int14 driver (if the nonconsole routines will ever be used)
  22.  
  23. shortcomings:
  24.   very simplistic
  25.   not a nice tpascal-type text file driver
  26.   minimal ansi/vt100 hard-coded in for nonconsole routines
  27.  
  28. requires:
  29.  
  30.   units:
  31.     uses dos,crt;  possibly mouse if mouse is $define'd
  32.  
  33.   variables:
  34.       console: boolean;
  35.       port: integer;  0=com1,1=com2,(untested 2=com3,3=com4)
  36.         note that this is fossil/bios convention, not dos convention!
  37.       shadow: integer; 0 for no shadowing to screen, n>0 for n/1000 sec delay
  38.       eightbitclean: boolean;
  39.       highcolor: integer;  0-255
  40.       lowcolor: integer;  0-255
  41.       readlnecho: boolean;
  42.  
  43.     if mapkey is defined
  44.       mainmap: array[char] of char;  (if mapkeys is defined)
  45.  
  46.     if timeout is defined
  47.       minstart: integer;  result of mitoday() at start
  48.       minlastinput: integer;  initialize to mitoday() at start
  49.       minutestorun: integer;  number of minutes to run, or -1 for no limit
  50.       idleminutes: integer;  number of idle minutes allowed
  51.       didtimeout: boolean;  initialize to false at start
  52.  
  53.   procedures:
  54.     mousehide,mouseshow;  if mouse is $define'd
  55.  
  56.   possible defines:
  57.     debug - print debug info on startup
  58.     consoleoverride - to allow console keyboard input to override serial
  59.     timeout - use timeout functions
  60.     mouse - use rodent in a simplistic manner
  61.     pgdnbecomesgt - translate pgdn to greater than -- otherwise space
  62.     xwritelnafterxreadln - otherwise up to caller
  63.     mapkeys - translation vector is in mainmap[] -- char c gets changed
  64.       to char mainmap[c] before being returned
  65.  
  66. interface:
  67.  
  68.   functions:
  69.     xkeypressed: boolean;
  70.     xreadkey: char;
  71.  
  72.   procedures:
  73.     portengage;
  74.     portdisengage;
  75.     portspeed(speed);
  76.     xwrites(s);
  77.     xwritei(i);
  78.     xwriteiw(i,w);
  79.     xwritess(s,s);
  80.     xwritesss(s,s,s);
  81.     xwriteln;
  82.     xwritelns(s);
  83.     xwritelnss(s,s);
  84.     xwritelnsss(s,s,s);
  85.     xgotoxy(x,y);
  86.     xwritexy(x,y,s);
  87.     xclreol;
  88.     xclreolxy(x,y);
  89.     xclrscr;
  90.     xreadlns(s,maxlen,keepcurrent);
  91.     xreadlnsp(s,maxlen,keepcurrent);
  92.     xhighvideo;
  93.     xlowvideo;
  94.     xwritehighlights(s: string);
  95.  
  96. }
  97.  
  98. {$ifndef timeout}
  99.   const
  100.     didtimeout=false;
  101. {$endif}
  102.  
  103. {$ifdef timeout}
  104.  
  105. function mitoday: integer; {minutes into today}
  106.  
  107. var
  108.   h,m,s,s00: word;
  109.  
  110. begin
  111.   gettime(h,m,s,s00);
  112.   mitoday := 60*h+m;
  113. end;
  114.  
  115. {$endif}
  116.  
  117. {$ifndef mouse}
  118.  
  119. procedure mousehide;
  120.  
  121. begin end;
  122.  
  123. procedure mouseshow;
  124.  
  125. begin end;
  126.  
  127. {$endif}
  128.  
  129. {serio:  header ends}
  130.  
  131. {serio:  actual serial i/o stuff begins}
  132.  
  133. procedure portengage;
  134.  
  135. var
  136.   regs: registers;
  137.  
  138. begin
  139.   regs.dx := port;
  140.   regs.ah := 4;
  141.   regs.bx := 0;
  142.   intr($14,regs);
  143.  
  144. {$ifdef debug}
  145.   writeln('serio:  portengage');
  146.   writeln('regs.ax=',regs.ax,' (6484 for a fossil driver)');
  147.   writeln('regs.bl=',regs.bl,' highest function supported');
  148.   writeln('regs.bh=',regs.bh,' version of fossil spec');
  149. {$endif}
  150.  
  151. end;
  152.  
  153. procedure portdisengage;
  154.  
  155. var
  156.   regs: registers;
  157.  
  158. begin
  159.   regs.dx := port;
  160.   regs.ah := 5;
  161.   intr($14,regs);
  162. end;
  163.  
  164. procedure portspeed(speed: longint);
  165.  
  166. var
  167.   regs: registers;
  168.   speedbyte: byte;
  169.  
  170. begin
  171.   speedbyte := 2;
  172.  
  173.   case speed of
  174.       600: speedbyte := 3;
  175.      1200: speedbyte := 4;
  176.      2400: speedbyte := 5;
  177.      4800: speedbyte := 6;
  178.      9600: speedbyte := 7;
  179.     19200: speedbyte := 0;
  180. {   38400: speedbyte := 1; }  {supported by some fossils}
  181.   end;
  182.   speedbyte := speedbyte shl 5;
  183.  
  184.   regs.dx := port;
  185.   regs.ah := 0;
  186.   regs.al := speedbyte or 3;
  187.   intr($14,regs);
  188. end;
  189.  
  190. procedure noncwritec(c: char);
  191.  
  192. var
  193.   regs: registers;
  194.  
  195. begin
  196.   regs.dx := port;
  197.   regs.ah := 1;
  198.   regs.al := ord(c);
  199.   intr($14,regs);
  200. end;
  201.  
  202. function noncreadc: char;
  203.  
  204. var
  205.   regs: registers;
  206.  
  207. begin
  208.   regs.dx := port;
  209.   regs.ah := 2;
  210.   intr($14,regs);
  211.   noncreadc := chr(regs.al);
  212. end;
  213.  
  214. function noncinready: boolean;
  215.  
  216. var
  217.   regs: registers;
  218.  
  219. begin
  220.   regs.dx := port;
  221.   regs.ah := 3;
  222.   intr($14,regs);
  223.   noncinready := odd(regs.ah);
  224. end;
  225.  
  226. {serio:  actual serial i/o stuff ends}
  227.  
  228. {serio:  initial output procedures begin}
  229.  
  230. procedure xwrites(s: string);
  231.  
  232. var
  233.   i: integer;
  234.  
  235. begin
  236.   if console then
  237.     begin
  238.       mousehide;
  239.       write(s);
  240.       mouseshow;
  241.     end
  242.   else
  243.     begin
  244.       for i := 1 to length(s) do
  245.         noncwritec(s[i]);
  246.       if shadow>0 then
  247.         begin
  248.           write(s);
  249. {$ifndef nocrtunit}
  250.           delay(shadow);
  251. {$endif}
  252.         end;
  253.     end;
  254. end;
  255.  
  256. procedure xwritei(i: integer);
  257.  
  258. var
  259.   s: string;
  260.  
  261. begin
  262.   if console then
  263.     begin
  264.       mousehide;
  265.       write(i);
  266.       mouseshow;
  267.     end
  268.   else
  269.     begin
  270.       str(i,s);
  271.       xwrites(s);
  272.     end;
  273. end;
  274.  
  275. procedure xwriteiw(i,w: integer);
  276.  
  277. var
  278.   s: string;
  279.  
  280. begin
  281.   if console then
  282.     begin
  283.       mousehide;
  284.       write(i:w);
  285.       mouseshow;
  286.     end
  287.   else
  288.     begin
  289.       str(i:w,s);
  290.       xwrites(s);
  291.     end;
  292. end;
  293.  
  294. procedure xwritess(s1,s2: string);
  295.  
  296. begin
  297.   xwrites(s1);
  298.   xwrites(s2);
  299. end;
  300.  
  301. procedure xwritesss(s1,s2,s3: string);
  302.  
  303. begin
  304.   xwrites(s1);
  305.   xwrites(s2);
  306.   xwrites(s3);
  307. end;
  308.  
  309. procedure xwriteln;
  310.  
  311. begin
  312.   if console then
  313.     begin
  314.       mousehide;
  315.       writeln;
  316.       mouseshow;
  317.     end
  318.   else
  319.     xwritess(chr(13),chr(10));
  320. end;
  321.  
  322. procedure xwritelns(s: string);
  323.  
  324. begin
  325.   xwrites(s);
  326.   xwriteln;
  327. end;
  328.  
  329. procedure xwritelnss(s1,s2: string);
  330.  
  331. begin
  332.   xwrites(s1);
  333.   xwrites(s2);
  334.   xwriteln;
  335. end;
  336.  
  337. procedure xwritelnsss(s1,s2,s3: string);
  338.  
  339. begin
  340.   xwrites(s1);
  341.   xwrites(s2);
  342.   xwrites(s3);
  343.   xwriteln;
  344. end;
  345.  
  346. {serio:  initial output procedures end}
  347.  
  348. {serio:  functions begin}
  349.  
  350. function xkeypressed: boolean;
  351.  
  352. var
  353.   result: boolean;
  354.   minnow: integer;
  355.  
  356. begin
  357.   result := false;
  358.  
  359. {$ifdef timeout}
  360.   didtimeout := false;
  361. {$endif}
  362.  
  363.   if console then
  364.     begin
  365. {$ifdef mouse}
  366.       if hasmouse then
  367.         result := keypressed or (mousevent.event<>0)
  368.       else
  369.         result := keypressed;
  370. {$else}
  371. {$ifdef nocrtunit}
  372.       writeln('no crt unit -- cannot use xkeypresssed');
  373.       halt(1);
  374. {$else}
  375.       result := keypressed;
  376. {$endif}
  377. {$endif}
  378.     end
  379.   else
  380.     begin
  381.  
  382. {check for timeout _before_ checking if a key is ready - modems can spew}
  383.  
  384. {$ifdef timeout}
  385.  
  386.       minnow := mitoday;
  387.       if minnow<minstart then
  388.         inc(minnow,24*60);
  389.  
  390.       if (minutestorun>=0) and (minnow-minstart>=minutestorun) then
  391.         begin
  392.           xwriteln;
  393.           xwritelns('time up');
  394.           xwriteln;
  395.           halt(2);
  396.         end;
  397.  
  398.       if minnow<minlastinput then
  399.         inc(minnow,24*60);
  400.  
  401.       if minnow-minlastinput>idleminutes then
  402.         begin
  403. {$ifdef timeoutreturnscr}
  404.           didtimeout := true;
  405.           result := true;
  406. {$else}
  407.           xwriteln;
  408.           xwritelns('idle timeout');
  409.           xwriteln;
  410.           halt(2);
  411. {$endif}
  412.         end;
  413.  
  414. {$endif}
  415.  
  416. {$ifdef consoleoverride}
  417.  
  418. {$ifdef mouse}
  419.       if hasmouse then
  420.         result := result or noncinready or keypressed or (mousevent.event<>0)
  421.       else
  422.         result := result or noncinready or keypressed;
  423. {$else}
  424.       result := result or noncinready or keypressed;
  425. {$endif}
  426.  
  427. {$else}
  428.       result := result or noncinready;
  429. {$endif}
  430.  
  431.     end;
  432.  
  433.   xkeypressed := result;
  434. end;
  435.  
  436. function xreadkeyextended(forcecolumn: integer; forcerow: integer;
  437.  beginrow, endrow: integer): char;
  438.  
  439. var
  440.   result: char;
  441.  
  442. {$ifdef mouse}
  443.   regs: registers;
  444.   wasx, wasy: byte;
  445.   newx, newy: byte;
  446. {$endif}
  447.  
  448. begin
  449.   if console then
  450.     begin
  451.  
  452. { ignore function keys, alt keys, numeric pad keys - translate to ' ' }
  453.  
  454.       repeat
  455.  
  456. {$ifdef mouse}
  457.  
  458.         repeat
  459.         { nothing - we're on the console }
  460.         until xkeypressed;
  461.  
  462.         if keypressed then
  463.           begin
  464.             result := readkey;
  465.           end
  466.         else
  467.           begin
  468.             wasx := wherex;
  469.             wasy := wherey;
  470.  
  471.             newx := 1+(mousevent.horiz div 8);
  472.             newy := 1+(mousevent.vert div 8);
  473.  
  474.             if forcecolumn<>0 then
  475.               newx := forcecolumn;
  476.             if forcerow<>0 then
  477.               newy := forcerow;
  478.  
  479.             if (newy>=beginrow) and (newy<=endrow) then
  480.               newx := 1;
  481.  
  482.             gotoxy(newx,newy);
  483.  
  484. {read character from screen}
  485.             regs.ah := 8;
  486.             regs.bh := 0;
  487.             intr($10,regs);
  488.  
  489.             result := chr(regs.al);
  490.  
  491.             gotoxy(wasx,wasy);
  492.             mousevent.event := 0;
  493.           end;
  494.  
  495. {$else}
  496.  
  497. {$ifdef nocrtunit}
  498.         writeln('cannot use xreadkey without crt unit');
  499.         halt(1);
  500. {$else}
  501.         result := readkey;
  502. {$endif}
  503.  
  504. {$endif}
  505.  
  506. {$ifndef nocrtunit}
  507.         if (result=#0) and keypressed then
  508.           begin
  509.             result := readkey;
  510.  
  511. { change these extended keys: }
  512.  
  513. {    2nd Char key pressed    code returned }
  514. {    -------- -----------    ------------- }
  515. {    I  73    PgUp           <             }
  516. {    Q  81    PgDn           space or >    }
  517. {    G  71    Home           ^             }
  518. {    O  79    End            $             }
  519. {    ;  59    F1             ?             }
  520. {    K  75    left arrow     backspace     }
  521. {    $  36    alt-J          !             }
  522.  
  523.             if result='I' then
  524.               result := '<'
  525. {$ifdef pgdnbecomesgt}
  526.             else if result='Q' then
  527.               result := '>'
  528. {$else}
  529.             else if result='Q' then
  530.               result := ' '
  531. {$endif}
  532.             else if result='G' then
  533.               result := '^'
  534.             else if result='O' then
  535.               result := '$'
  536.             else if result=';' then
  537.               result := '?'
  538.             else if result='K' then
  539.               result := #8
  540.             else if result='$' then
  541.               result := '!'
  542.             else
  543.  
  544. { ignore other extended keys }
  545.  
  546.               result := #0;
  547.  
  548.           end;
  549. {$endif}
  550.  
  551.       until result<>#0;
  552.     end
  553.   else
  554.     begin
  555.       while not xkeypressed do
  556.         ;
  557.  
  558.       if didtimeout then
  559.         begin
  560. {$ifdef timeout}
  561.           didtimeout := false;
  562. {$endif}
  563.           result := #13;
  564.         end
  565.       else
  566.         begin
  567.  
  568. {$ifdef consoleoverride}
  569.           if keypressed then
  570.             result := readkey
  571.           else
  572. {$endif}
  573.             result := noncreadc;
  574.  
  575.         end;
  576.  
  577.     end;
  578.  
  579. {$ifdef mapkeys}
  580.   result := mainmap[result];
  581. {$endif}
  582.  
  583.   xreadkeyextended := result;
  584. end;
  585.  
  586. function xreadkey: char;
  587.  
  588. begin
  589.   xreadkey := xreadkeyextended(0,0,0,0);
  590. end;
  591.  
  592. {serio:  functions end}
  593.  
  594. {serio:  procedures begin}
  595.  
  596. procedure xgotoxy(x,y: integer);
  597.  
  598. begin
  599.   if console then
  600.     begin
  601.       mousehide;
  602. {$ifdef nocrtunit}
  603.       writeln('cannot use xgotoxy without crt unit');
  604.       halt(1);
  605. {$else}
  606.       gotoxy(x,y);
  607. {$endif}
  608.       mouseshow;
  609.     end
  610.   else
  611.     begin
  612.       xwritess(#27,'[');
  613.       xwritei(y);
  614.       xwrites(';');
  615.       xwritei(x);
  616.       xwrites('f');
  617.     end;
  618. end;
  619.  
  620. procedure xwritexy(x,y: integer; s: string);
  621.  
  622. begin
  623.   xgotoxy(x,y);
  624.   xwrites(s);
  625. end;
  626.  
  627. procedure xclreol;
  628.  
  629. begin
  630.   if console then
  631.     begin
  632.       mousehide;
  633. {$ifdef nocrtunit}
  634.       writeln('cannot use xclreol without crt unit');
  635.       halt(1);
  636. {$else}
  637.       clreol;
  638. {$endif}
  639.       mouseshow;
  640.     end
  641.   else
  642.     xwritess(#27,'[0K');
  643. end;
  644.  
  645. procedure xclreolxy(x,y: integer);
  646.  
  647. begin
  648.   xgotoxy(x,y);
  649.   xclreol;
  650. end;
  651.  
  652. procedure xclrscr;
  653.  
  654. begin
  655.   if console then
  656.     begin
  657.       mousehide;
  658. {$ifdef nocrtunit}
  659.       writeln('cannot use xclrscr without crt unit');
  660.       halt(1);
  661. {$else}
  662.       clrscr;
  663. {$endif}
  664.       mouseshow;
  665.     end
  666.   else
  667.     begin
  668.       xwritess(#27,'[2J');
  669.       xgotoxy(1,1);
  670.     end;
  671. end;
  672.  
  673. procedure xreadlns(var s: string; maxlen: integer; keepcurrent: boolean);
  674.  
  675. var
  676.   result: string;
  677.   len: integer;
  678.   c: char;
  679.  
  680. begin
  681.   if keepcurrent then
  682.     result := s
  683.   else
  684.     result := '';
  685.   len := length(result);
  686.   xwrites(result);
  687.   repeat
  688.     c := xreadkey;
  689.     if (c=#127) or (c=#8) then
  690.       begin
  691.         if length(result)>0 then
  692.           begin
  693.             if readlnecho then
  694.               xwritesss(#8,' ',#8);
  695.             dec(len);
  696.             if len=0 then
  697.               result := ''
  698.             else
  699.               result := copy(result,1,len);
  700.           end;
  701.       end
  702.     else if (c=#13) then
  703.       begin
  704. {$ifdef xwritelnafterxreadln}
  705.         xwriteln;
  706. {$endif}
  707.       end
  708.     else if (c=#21) then   { control-U }
  709.       begin
  710.         while len>0 do
  711.           begin
  712.             if readlnecho then
  713.               xwritesss(#8,' ',#8);
  714.             dec(len);
  715.           end;
  716.         result := '';
  717.       end
  718.     else if (ord(c)>=32) and (eightbitclean or (ord(c)<128))
  719.      and (len<maxlen) then
  720.       begin
  721.         inc(len);
  722.         result := result+c;
  723.         if readlnecho then
  724.           begin
  725.             if console then
  726.               begin
  727.                 mousehide;
  728.                 write(c);
  729.                 mouseshow;
  730.               end
  731.             else
  732.               noncwritec(c);
  733.           end;
  734.       end
  735.   until c=#13;
  736.   s := result;
  737. end;
  738.  
  739. procedure xreadlnsp(var s: string; maxlen: integer; keepcurrent: boolean);
  740.  
  741. {readln, can end with SPACE or RETURN}
  742.  
  743. var
  744.   result: string;
  745.   len: integer;
  746.   c: char;
  747.  
  748. begin
  749.   if keepcurrent then
  750.     result := s
  751.   else
  752.     result := '';
  753.   len := length(result);
  754.   xwrites(result);
  755.   repeat
  756.     c := xreadkey;
  757.     if (c=#127) or (c=#8) then
  758.       begin
  759.         if length(result)>0 then
  760.           begin
  761.             if readlnecho then
  762.               xwritesss(#8,' ',#8);
  763.             dec(len);
  764.             if len=0 then
  765.               result := ''
  766.             else
  767.               result := copy(result,1,len);
  768.           end;
  769.       end
  770.     else if (c=#13) or (c=' ') then
  771.       begin
  772. {$ifdef xwritelnafterxreadln}
  773.         xwriteln;
  774. {$endif}
  775.       end
  776.     else if (c=#21) then   { control-U }
  777.       begin
  778.         while len>0 do
  779.           begin
  780.             if readlnecho then
  781.               xwritesss(#8,' ',#8);
  782.             dec(len);
  783.           end;
  784.         result := '';
  785.       end
  786.     else if (ord(c)>=32) and (eightbitclean or (ord(c)<128))
  787.      and (len<maxlen) then
  788.       begin
  789.         inc(len);
  790.         result := result+c;
  791.         if readlnecho then
  792.           begin
  793.             if console then
  794.               begin
  795.                 mousehide;
  796.                 write(c);
  797.                 mouseshow;
  798.               end
  799.             else
  800.               noncwritec(c);
  801.           end;
  802.       end
  803.   until (c=#13) or (c=' ');
  804.   s := result;
  805. end;
  806.  
  807. procedure xhighvideo;
  808.  
  809. {color is 0-15, background is 0-7}
  810.  
  811. begin
  812.   if console then
  813.     begin
  814. {$ifdef nocrtunit}
  815.       writeln('cannot use xhighvideo without crt unit');
  816.       halt(1);
  817. {$else}
  818.       textcolor(highcolor and $f);
  819.       textbackground(highcolor shr 4);
  820. {$endif}
  821.     end
  822.   else
  823.     xwritess(#27,'[7m');
  824. end;
  825.  
  826. procedure xlowvideo;
  827.  
  828. {color is 0-15, background is 0-7}
  829.  
  830. begin
  831.   if console then
  832.     begin
  833. {$ifdef nocrtunit}
  834.       writeln('cannot use xlowvideo without crt unit');
  835.       halt(1);
  836. {$else}
  837.       textcolor(lowcolor and $f);
  838.       textbackground(lowcolor shr 4);
  839. {$endif}
  840.     end
  841.   else
  842.     xwritess(#27,'[m');
  843. end;
  844.  
  845. procedure xwritehighlights(s: string);
  846.  
  847. var
  848.   i: integer;
  849.  
  850. begin
  851.   for i := 1 to length(s) do
  852.     if s[i]='<' then
  853.       xhighvideo
  854.     else if s[i]='>' then
  855.       xlowvideo
  856.     else
  857.       xwrites(s[i]);
  858. end;
  859.  
  860. {serio:  procedures end}
  861.  
  862. {serio.pas ends}
  863.